@rahularya01/pi-essentials 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +324 -0
- package/examples/mcp.json +30 -0
- package/examples/pi-essentials.json +32 -0
- package/examples/pi-settings.json +5 -0
- package/package.json +88 -0
- package/skills/pi-essentials/SKILL.md +50 -0
- package/src/config.ts +351 -0
- package/src/errors.ts +96 -0
- package/src/index.ts +43 -0
- package/src/mcp/commands.ts +390 -0
- package/src/mcp/config.ts +157 -0
- package/src/mcp/credential-store.ts +153 -0
- package/src/mcp/index.ts +67 -0
- package/src/mcp/manager.ts +941 -0
- package/src/mcp/oauth.ts +262 -0
- package/src/mcp/proxy-tool.ts +213 -0
- package/src/mcp/render.ts +164 -0
- package/src/mcp/types.ts +63 -0
- package/src/paths.ts +48 -0
- package/src/questions/ask.ts +134 -0
- package/src/questions/index.ts +72 -0
- package/src/questions/render.ts +69 -0
- package/src/questions/validate.ts +85 -0
- package/src/security/env.ts +132 -0
- package/src/security/limits.ts +20 -0
- package/src/security/ssrf.ts +237 -0
- package/src/subagents/activity.ts +132 -0
- package/src/subagents/builtins/oracle.md +11 -0
- package/src/subagents/builtins/reviewer.md +11 -0
- package/src/subagents/builtins/scout.md +12 -0
- package/src/subagents/builtins/worker.md +11 -0
- package/src/subagents/discover.ts +54 -0
- package/src/subagents/herdr.ts +150 -0
- package/src/subagents/index.ts +642 -0
- package/src/subagents/inspector-tail.d.mts +1 -0
- package/src/subagents/inspector-tail.mjs +140 -0
- package/src/subagents/render.ts +464 -0
- package/src/subagents/runner.ts +468 -0
- package/src/subagents/schema.ts +107 -0
- package/src/subagents/types.ts +131 -0
- package/src/subagents/worktree.ts +131 -0
- package/src/todos/index.ts +170 -0
- package/src/todos/render.ts +198 -0
- package/src/todos/state.ts +310 -0
- package/src/ui/render.ts +215 -0
- package/src/web/activity.ts +91 -0
- package/src/web/cache.ts +153 -0
- package/src/web/extract.ts +75 -0
- package/src/web/fetch.ts +167 -0
- package/src/web/html-to-markdown.ts +284 -0
- package/src/web/http.ts +238 -0
- package/src/web/index.ts +214 -0
- package/src/web/providers/brave.ts +27 -0
- package/src/web/providers/duckduckgo.ts +60 -0
- package/src/web/providers/exa.ts +29 -0
- package/src/web/providers/jina.ts +25 -0
- package/src/web/providers/searxng.ts +29 -0
- package/src/web/providers/tavily.ts +31 -0
- package/src/web/providers/types.ts +75 -0
- package/src/web/render.ts +130 -0
- package/src/web/search.ts +108 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Rahul Arya
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
# pi-essentials
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/@rahularya01/pi-essentials)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://github.com/Rahularya01/pi-essentials/actions/workflows/ci.yml)
|
|
6
|
+
[](https://github.com/sponsors/Rahularya01)
|
|
7
|
+
|
|
8
|
+
**pi-essentials** (currently in beta) is a battery-included extensions bundle for the [Pi Coding Agent](https://pi.dev) that adds **Model Context Protocol (MCP)**, **Web access (search & fetch)**, **Subagents**, **Todos**, and **Structured user questions** in a single, lightweight plugin.
|
|
9
|
+
|
|
10
|
+
Pi itself ships without these capabilities. `pi-essentials` registers them with a single shared configuration, zero external runtime bloat, and a security-first architecture. It does **not** wrap `pi-mcp-adapter`, `pi-web-access`, or juicesharp packages — it follows their proven patterns (proxy MCP tool, Readability extraction, isolated child sessions, session-branch todos) with a smaller, original surface.
|
|
11
|
+
|
|
12
|
+
> Using Google Antigravity / Gemini models with Pi? Pair this with the companion provider extension [`pi-antigravity`](https://github.com/Rahularya01/pi-antigravity).
|
|
13
|
+
|
|
14
|
+
## Contents
|
|
15
|
+
|
|
16
|
+
- [Requirements](#requirements)
|
|
17
|
+
- [Install](#install)
|
|
18
|
+
- [Quick start](#quick-start)
|
|
19
|
+
- [Commands](#commands)
|
|
20
|
+
- [MCP (Model Context Protocol)](#mcp-model-context-protocol)
|
|
21
|
+
- [Web access](#web-access)
|
|
22
|
+
- [Subagents](#subagents)
|
|
23
|
+
- [Todos](#todos)
|
|
24
|
+
- [Ask the user](#ask-the-user)
|
|
25
|
+
- [Terminal UI and panels](#terminal-ui-and-panels)
|
|
26
|
+
- [Configuration](#configuration)
|
|
27
|
+
- [Security](#security)
|
|
28
|
+
- [Development](#development)
|
|
29
|
+
- [Support the project](#support-the-project)
|
|
30
|
+
- [License](#license)
|
|
31
|
+
|
|
32
|
+
## Requirements
|
|
33
|
+
|
|
34
|
+
- Node.js **22 or later** (uses native TypeScript type-stripping, zero build step required)
|
|
35
|
+
- Pi Coding Agent (`@earendil-works/pi-coding-agent`) version **0.80.0 or later**
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
Install from npm:
|
|
40
|
+
|
|
41
|
+
```bash
|
|
42
|
+
pi install npm:@rahularya01/pi-essentials
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Or install directly from GitHub:
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pi install git:github.com/Rahularya01/pi-essentials
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
Or from a local checkout:
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
pi install /absolute/path/to/pi-essentials
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Or add it to your global `~/.pi/agent/settings.json` or project `.pi/settings.json`:
|
|
58
|
+
|
|
59
|
+
```json
|
|
60
|
+
{
|
|
61
|
+
"packages": ["npm:@rahularya01/pi-essentials"]
|
|
62
|
+
}
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Restart Pi (or run `/reload`) after installation. To update the package later, use `pi update npm:@rahularya01/pi-essentials`.
|
|
66
|
+
|
|
67
|
+
## Quick start
|
|
68
|
+
|
|
69
|
+
1. Install the extension: `pi install npm:@rahularya01/pi-essentials`.
|
|
70
|
+
2. Configure any MCP servers you need in `.mcp.json` or `~/.config/mcp/mcp.json`.
|
|
71
|
+
3. Start Pi. Type `/mcp` for an interactive server management hub, or `/todos` to view active tasks.
|
|
72
|
+
4. Prompt Pi naturally — it will discover MCP tools on demand, perform web research, spawn subagents, and keep track of todos automatically.
|
|
73
|
+
|
|
74
|
+
## Commands
|
|
75
|
+
|
|
76
|
+
| Command | Description |
|
|
77
|
+
|---|---|
|
|
78
|
+
| `/mcp` | Interactive server management hub (or shows status table in non-interactive mode) |
|
|
79
|
+
| `/mcp tools` | Connect and list all discovered tools across configured MCP servers |
|
|
80
|
+
| `/mcp enable [server]` | Enable an MCP server (opens an interactive selector if omitted in TUI) |
|
|
81
|
+
| `/mcp disable [server]` | Disable an MCP server (opens an interactive selector if omitted in TUI) |
|
|
82
|
+
| `/mcp auth [server] [url]` | Authenticate an OAuth MCP server (interactive selector if omitted in TUI) |
|
|
83
|
+
| `/mcp-auth [server]` | Dedicated shortcut to authenticate with an OAuth MCP server |
|
|
84
|
+
| `/mcp auth-start <server>` | Initiate OAuth and output the authorization URL immediately |
|
|
85
|
+
| `/mcp auth-complete <server> <url>` | Complete an OAuth flow with pasted redirect URL or code |
|
|
86
|
+
| `/mcp reconnect [server]` | Reconnect a specific server or all active servers |
|
|
87
|
+
| `/mcp logout <server>` | Clear stored OAuth credentials for a server |
|
|
88
|
+
| `/mcp disconnect [server]` | Disconnect an active server or all servers |
|
|
89
|
+
| `/todos` | Print current session todos grouped by status |
|
|
90
|
+
| `/todos clear` | Clear todos in the current session branch |
|
|
91
|
+
| `/subagents` | Open the interactive two-column fleet inspector |
|
|
92
|
+
| `/subagents pane [id]` | Open a running child subagent in an external Herdr pane |
|
|
93
|
+
| `/subagents cancel <id\|all>` | Cancel running subagent tasks |
|
|
94
|
+
| `/web` | Show recent web search and fetch activity (timing, size, outcome) |
|
|
95
|
+
| `/web clear` | Clear web activity log |
|
|
96
|
+
|
|
97
|
+
All `/mcp` subcommands and server names support **Tab autosuggestions**.
|
|
98
|
+
|
|
99
|
+
## MCP (Model Context Protocol)
|
|
100
|
+
|
|
101
|
+
Reads standard MCP configuration files, with project-level files overriding user-level files:
|
|
102
|
+
|
|
103
|
+
1. `~/.config/mcp/mcp.json`
|
|
104
|
+
2. `~/.agents/mcp.json`
|
|
105
|
+
3. `~/.agents/mcp/mcp.json`
|
|
106
|
+
4. `~/.pi/agent/mcp.json`
|
|
107
|
+
5. `.mcp.json`
|
|
108
|
+
6. `.pi/mcp.json`
|
|
109
|
+
|
|
110
|
+
Supports stdio (`command`/`args`) and HTTP (`url`), with Streamable HTTP and automatic SSE fallback. Servers are **lazy** by default: they start on first use and automatically disconnect after an idle timeout. One proxy tool keeps MCP schemas out of the model's context until needed.
|
|
111
|
+
|
|
112
|
+
```js
|
|
113
|
+
mcp({ action: "search", query: "screenshot" })
|
|
114
|
+
mcp({ action: "describe", tool: "chrome_devtools_take_screenshot" })
|
|
115
|
+
mcp({ action: "call", tool: "chrome_devtools_take_screenshot", args: { format: "png" } })
|
|
116
|
+
mcp({ action: "status" })
|
|
117
|
+
mcp({ action: "enable", server: "linear" })
|
|
118
|
+
mcp({ action: "disable", server: "linear" })
|
|
119
|
+
mcp({ action: "auth", server: "linear" })
|
|
120
|
+
mcp({ action: "auth-start", server: "linear" })
|
|
121
|
+
mcp({ action: "auth-complete", server: "linear", redirectUrl: "http://127.0.0.1:5173/callback?code=...&state=..." })
|
|
122
|
+
mcp({ action: "auth-complete", server: "linear", code: "..." })
|
|
123
|
+
mcp({ action: "logout", server: "linear" })
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
Servers can share defaults through a `settings` block in the same file:
|
|
127
|
+
|
|
128
|
+
```json
|
|
129
|
+
{ "settings": { "requestTimeoutMs": 30000, "idleTimeout": 10 }, "mcpServers": { } }
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
- **Autosuggestions & Dialogs:** Typing `/mcp <Tab>` suggests subcommands; `/mcp enable <Tab>` or `/mcp auth <Tab>` suggests servers. Running `/mcp enable` or `/mcp disable` without arguments in the TUI opens an interactive selector (`ctx.ui.select`).
|
|
133
|
+
- **Persistent Overrides:** Toggling server status via `/mcp enable` or `/mcp disable` persists the setting in `.pi/mcp.json` without modifying the global config file.
|
|
134
|
+
- **OAuth Security:** Uses PKCE and a temporary loopback callback. Tokens prefer the OS credential store (macOS Keychain, Windows Credential Manager, Linux Secret Service) with fallback to a strict mode `0600` file (`~/.pi/agent/pi-essentials/mcp-oauth.json`).
|
|
135
|
+
|
|
136
|
+
Example server file: [`examples/mcp.json`](examples/mcp.json).
|
|
137
|
+
|
|
138
|
+
## Web access
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
web_search({ query: "TypeScript Pi coding agent extensions", numResults: 5 })
|
|
142
|
+
web_fetch({ url: "https://pi.dev/docs/latest/extensions" })
|
|
143
|
+
web_fetch({ url: "https://example.com/long", offset: 32000, limit: 8000 })
|
|
144
|
+
web_fetch({ cacheId: "abc123", offset: 32000, limit: 8000 })
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
- **`web_search`**: Supports query aliases (`numResults`, `limit`, `num_search_results`). Fallback chain across unconfigured providers: SearXNG → Brave → Tavily → Exa → Jina → DuckDuckGo.
|
|
148
|
+
- **`web_fetch`**: Requires either `url` or `cacheId`. Extracts clean markdown using Mozilla Readability, truncates large pages gracefully, and caches full text for one hour.
|
|
149
|
+
- **SSRF Hardened**: Never executes page JavaScript. Blocks private, loopback, link-local, CGNAT, and cloud-metadata addresses on every redirect hop, with DNS-pinning to prevent rebinding attacks. Trust private services explicitly via `web.allowedHosts`.
|
|
150
|
+
|
|
151
|
+
## Subagents
|
|
152
|
+
|
|
153
|
+
```js
|
|
154
|
+
subagent({ agent: "scout", task: "Find the auth entry points" })
|
|
155
|
+
subagent({
|
|
156
|
+
tasks: [
|
|
157
|
+
{ agent: "reviewer", task: "Review tests" },
|
|
158
|
+
{ agent: "reviewer", task: "Review error handling" }
|
|
159
|
+
]
|
|
160
|
+
})
|
|
161
|
+
subagent({
|
|
162
|
+
chain: [
|
|
163
|
+
{ agent: "scout", task: "Map the payment flow" },
|
|
164
|
+
{ agent: "oracle", task: "Challenge this plan: {previous}" }
|
|
165
|
+
]
|
|
166
|
+
})
|
|
167
|
+
subagent({
|
|
168
|
+
agent: "worker",
|
|
169
|
+
task: "Implement the parser",
|
|
170
|
+
outputSchema: {
|
|
171
|
+
type: "object",
|
|
172
|
+
properties: { summary: { type: "string" } },
|
|
173
|
+
required: ["summary"]
|
|
174
|
+
},
|
|
175
|
+
isolation: "worktree"
|
|
176
|
+
})
|
|
177
|
+
```
|
|
178
|
+
|
|
179
|
+
- **Built-in Agents**: `scout`, `reviewer`, `worker`, `oracle`. Custom agents can be added as markdown files in `~/.pi/agent/agents/` or `.pi/agents/`.
|
|
180
|
+
- **Isolated Sessions**: Children run as separate `pi --mode json --no-session` child processes with sanitized environments (`MCP_*` and API secrets stripped; model credentials forwarded).
|
|
181
|
+
- **Worktree Isolation**: `isolation: "worktree"` runs work against a temporary detached Git worktree at `HEAD`, returning changed files and a clean patch artifact without modifying your working tree.
|
|
182
|
+
- **Live Fleet Inspector**: Press `↓` or `←` with the editor empty to expand the fleet roster, or run `/subagents` to open a two-column interactive live transcript inspector. Press `h` (or `/subagents pane [id]`) to open the child in an external [Herdr](https://github.com/herdrdev/herdr) pane.
|
|
183
|
+
|
|
184
|
+
## Todos
|
|
185
|
+
|
|
186
|
+
```js
|
|
187
|
+
todo({ action: "create", content: "Implement feature", phase: "build" })
|
|
188
|
+
todo({ action: "create", content: "Add repository tests", phase: "verify", blockedBy: [1] })
|
|
189
|
+
todo({ action: "update", id: 2, status: "in_progress" })
|
|
190
|
+
todo({ action: "block", id: 2, blocker: "Waiting for CI" })
|
|
191
|
+
todo({ action: "complete", id: 1 })
|
|
192
|
+
todo({ action: "list" })
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
- **Status Workflow**: `pending`, `in_progress`, `completed`, `blocked`, `abandoned`.
|
|
196
|
+
- **Session-Branch Persistence**: State is tied to the active session tree branch, surviving `/reload`, compaction, and `/tree` navigation.
|
|
197
|
+
- **Dependency Tracking**: `blockedBy` enforces valid DAG relationships, rejecting cycles and warning when selecting a blocked task. Completing an item automatically announces unblocked tasks.
|
|
198
|
+
- **Interactive Panel**: Displays an unobtrusive checklist widget right above the editor.
|
|
199
|
+
|
|
200
|
+
## Ask the user
|
|
201
|
+
|
|
202
|
+
```js
|
|
203
|
+
ask_user_question({
|
|
204
|
+
questions: [
|
|
205
|
+
{
|
|
206
|
+
id: "cache",
|
|
207
|
+
question: "Which cache should we add?",
|
|
208
|
+
options: [
|
|
209
|
+
{ label: "In-memory", value: "memory", description: "Fast, per-process" },
|
|
210
|
+
{ label: "Redis", value: "redis", description: "Shared, extra ops" },
|
|
211
|
+
{ label: "None", value: "none", description: "Skip caching" }
|
|
212
|
+
],
|
|
213
|
+
recommended: 0,
|
|
214
|
+
allowOther: true,
|
|
215
|
+
multiple: false
|
|
216
|
+
}
|
|
217
|
+
]
|
|
218
|
+
})
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
- Prompts the user with an interactive modal in the terminal when a real human decision is required.
|
|
222
|
+
- Supports single-choice, multi-select, and custom write-in answers.
|
|
223
|
+
- Erased automatically in non-interactive/headless runs.
|
|
224
|
+
|
|
225
|
+
## Terminal UI and panels
|
|
226
|
+
|
|
227
|
+
Three contextual panels wrap around the editor, collapsing to a single line when idle:
|
|
228
|
+
|
|
229
|
+
| Panel | Placement | Shortcut | Purpose |
|
|
230
|
+
|---|---|---|---|
|
|
231
|
+
| Todos | Above editor | `ctrl+shift+t` | Live progress bar and task checklist |
|
|
232
|
+
| Subagent fleet | Below editor | `ctrl+shift+a` | Active child runs, token counts, and costs |
|
|
233
|
+
| Web activity | Below editor | `ctrl+shift+w` | Search queries, HTTP status, and fetch sizes |
|
|
234
|
+
| Tool output expand | Tool card | `ctrl+o` | Expand compact tool result into full detail |
|
|
235
|
+
|
|
236
|
+
```
|
|
237
|
+
── Todos ───────────────────────────── ▪▪▪▪▫▫▫▫▫▫ 2/5
|
|
238
|
+
▶ #3 Wire the activity panel
|
|
239
|
+
○ #4 Update the README · needs #3
|
|
240
|
+
✓ #1 R̶e̶a̶d̶ ̶t̶h̶e̶ ̶d̶o̶c̶s̶
|
|
241
|
+
+1 more (1 completed)
|
|
242
|
+
|
|
243
|
+
2 running agents · 5/16 spawned · ↓/← to inspect
|
|
244
|
+
|
|
245
|
+
── Web activity ───────────────────────────── 3 recent
|
|
246
|
+
FETCH blog.example.com/gone HTTP 404 260ms ✗
|
|
247
|
+
FETCH nodejs.org/api/stream.html 194.8k chars 812ms ✓
|
|
248
|
+
SEARCH "typescript streams" 5 hits 2.1s ✓
|
|
249
|
+
```
|
|
250
|
+
|
|
251
|
+
A live footer widget tracks MCP connection status: `⚡ mcp 2/3 · 1 need auth`.
|
|
252
|
+
|
|
253
|
+
## Configuration
|
|
254
|
+
|
|
255
|
+
Create `~/.pi/agent/pi-essentials.json`, and optionally override it with `.pi/pi-essentials.json` per project. Later files win.
|
|
256
|
+
|
|
257
|
+
```json
|
|
258
|
+
{
|
|
259
|
+
"mcp": true,
|
|
260
|
+
"web": {
|
|
261
|
+
"enabled": true,
|
|
262
|
+
"search": { "provider": "auto", "braveApiKey": "BSA_..." }
|
|
263
|
+
},
|
|
264
|
+
"subagents": { "enabled": true, "maxConcurrency": 4, "spawnBudget": 16 },
|
|
265
|
+
"todos": true,
|
|
266
|
+
"questions": true
|
|
267
|
+
}
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
| Option | Default | Meaning |
|
|
271
|
+
|---|---|---|
|
|
272
|
+
| `mcp.requestTimeoutMs` | `30000` | Per-request MCP timeout in milliseconds |
|
|
273
|
+
| `mcp.idleTimeoutMs` | `600000` | Disconnect an idle MCP server after this duration (10 min) |
|
|
274
|
+
| `web.search.provider` | `"auto"` | Force a search provider or use the fallback chain |
|
|
275
|
+
| `web.search.timeoutMs` | `15000` | Per-request search timeout |
|
|
276
|
+
| `web.search.maxResults` | `5` | Default number of search results returned (1-20) |
|
|
277
|
+
| `web.fetch.timeoutMs` | `15000` | Per-request fetch timeout |
|
|
278
|
+
| `web.fetch.maxBytes` | `2097152` | Download cap before page download is cut short (2 MB) |
|
|
279
|
+
| `web.fetch.maxChars` | `32000` | Maximum characters returned to the model per call |
|
|
280
|
+
| `web.fetch.jinaFallback` | `true` | Retry failed page fetches via `r.jina.ai` |
|
|
281
|
+
| `web.allowedHosts` | `[]` | Private hosts to deliberately trust, as `host` or `host:port` |
|
|
282
|
+
| `subagents.maxConcurrency` | `4` | Maximum child subagents executing simultaneously |
|
|
283
|
+
| `subagents.maxParallel` | `8` | Maximum tasks allowed in a single parallel call |
|
|
284
|
+
| `subagents.maxOutputBytes` | `51200` | UTF-8 byte cap on returned subagent answers (50 KB) |
|
|
285
|
+
| `subagents.spawnBudget` | `16` | Total children allowed per session |
|
|
286
|
+
| `subagents.allowNested` | `false` | Allow children to spawn their own subagents |
|
|
287
|
+
| `subagents.herdr` | `true` | Allow opening a child in an external Herdr pane |
|
|
288
|
+
|
|
289
|
+
Environment variables for search backends: `BRAVE_API_KEY`, `TAVILY_API_KEY`, `EXA_API_KEY`, `JINA_API_KEY`, and `SEARXNG_URL`.
|
|
290
|
+
|
|
291
|
+
See [`examples/pi-essentials.json`](examples/pi-essentials.json) and [`examples/pi-settings.json`](examples/pi-settings.json).
|
|
292
|
+
|
|
293
|
+
## Security
|
|
294
|
+
|
|
295
|
+
- **Safe Execution**: No `eval`, no install/postinstall scripts, no shell interpolation of untrusted input (`spawn` argv arrays only).
|
|
296
|
+
- **Web Safety**: HTML/text parsing only; JavaScript is never executed. Strict DNS resolution checks with IP pinning prevent DNS rebinding and SSRF into private networks.
|
|
297
|
+
- **Decompression Protection**: Bounded by both compressed and decompressed size limits to prevent decompression bombs.
|
|
298
|
+
- **Subagent Sandboxing**: Children run with clean environments stripped of MCP secrets and third-party tokens. Only necessary provider credentials are forwarded.
|
|
299
|
+
- **Zero Silent Failures**: Tool errors throw explicitly so Pi registers them as genuine errors rather than misleading assistant text.
|
|
300
|
+
|
|
301
|
+
## Development
|
|
302
|
+
|
|
303
|
+
```bash
|
|
304
|
+
npm install
|
|
305
|
+
npm run check # typecheck + test suite
|
|
306
|
+
npm test
|
|
307
|
+
npm run typecheck
|
|
308
|
+
```
|
|
309
|
+
|
|
310
|
+
See [AGENTS.md](AGENTS.md) for architectural invariants and development rules.
|
|
311
|
+
|
|
312
|
+
## Support the project
|
|
313
|
+
|
|
314
|
+
If `pi-essentials` is useful to you, consider [sponsoring the project on GitHub](https://github.com/sponsors/Rahularya01).
|
|
315
|
+
|
|
316
|
+
## License
|
|
317
|
+
|
|
318
|
+
[MIT](LICENSE)
|
|
319
|
+
|
|
320
|
+
## Community
|
|
321
|
+
|
|
322
|
+
- [Contributing](CONTRIBUTING.md)
|
|
323
|
+
- [Code of Conduct](CODE_OF_CONDUCT.md)
|
|
324
|
+
- [Security policy](SECURITY.md)
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"settings": {
|
|
3
|
+
"requestTimeoutMs": 30000,
|
|
4
|
+
"idleTimeout": 10
|
|
5
|
+
},
|
|
6
|
+
"mcpServers": {
|
|
7
|
+
"filesystem": {
|
|
8
|
+
"command": "npx",
|
|
9
|
+
"args": [
|
|
10
|
+
"-y",
|
|
11
|
+
"@modelcontextprotocol/server-filesystem",
|
|
12
|
+
"/tmp"
|
|
13
|
+
],
|
|
14
|
+
"lifecycle": "lazy"
|
|
15
|
+
},
|
|
16
|
+
"remote-docs": {
|
|
17
|
+
"url": "https://mcp.example.com/mcp",
|
|
18
|
+
"headers": {
|
|
19
|
+
"Authorization": "Bearer ${MCP_DOCS_TOKEN}"
|
|
20
|
+
},
|
|
21
|
+
"auth": "bearer",
|
|
22
|
+
"requestTimeoutMs": 45000
|
|
23
|
+
},
|
|
24
|
+
"linear": {
|
|
25
|
+
"url": "https://mcp.linear.app/mcp",
|
|
26
|
+
"auth": "oauth",
|
|
27
|
+
"lifecycle": "lazy"
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"mcp": {
|
|
3
|
+
"enabled": true,
|
|
4
|
+
"requestTimeoutMs": 30000,
|
|
5
|
+
"idleTimeoutMs": 600000
|
|
6
|
+
},
|
|
7
|
+
"web": {
|
|
8
|
+
"enabled": true,
|
|
9
|
+
"allowedHosts": [],
|
|
10
|
+
"search": {
|
|
11
|
+
"provider": "auto",
|
|
12
|
+
"timeoutMs": 15000,
|
|
13
|
+
"maxResults": 5
|
|
14
|
+
},
|
|
15
|
+
"fetch": {
|
|
16
|
+
"timeoutMs": 15000,
|
|
17
|
+
"maxBytes": 2097152,
|
|
18
|
+
"maxChars": 32000,
|
|
19
|
+
"jinaFallback": true
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"subagents": {
|
|
23
|
+
"enabled": true,
|
|
24
|
+
"maxConcurrency": 4,
|
|
25
|
+
"maxParallel": 8,
|
|
26
|
+
"maxOutputBytes": 51200,
|
|
27
|
+
"spawnBudget": 16,
|
|
28
|
+
"allowNested": false
|
|
29
|
+
},
|
|
30
|
+
"todos": true,
|
|
31
|
+
"questions": true
|
|
32
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rahularya01/pi-essentials",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Cohesive Pi Coding Agent plugin: MCP, web access, subagents, todos, and ask-user questions.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"keywords": [
|
|
8
|
+
"pi-package",
|
|
9
|
+
"pi",
|
|
10
|
+
"mcp",
|
|
11
|
+
"coding-agent"
|
|
12
|
+
],
|
|
13
|
+
"author": "Rahul Arya",
|
|
14
|
+
"homepage": "https://github.com/Rahularya01/pi-essentials#readme",
|
|
15
|
+
"bugs": {
|
|
16
|
+
"url": "https://github.com/Rahularya01/pi-essentials/issues"
|
|
17
|
+
},
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/Rahularya01/pi-essentials.git"
|
|
21
|
+
},
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public"
|
|
24
|
+
},
|
|
25
|
+
"main": "./src/index.ts",
|
|
26
|
+
"exports": {
|
|
27
|
+
".": "./src/index.ts"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"src",
|
|
31
|
+
"skills",
|
|
32
|
+
"examples",
|
|
33
|
+
"README.md",
|
|
34
|
+
"LICENSE"
|
|
35
|
+
],
|
|
36
|
+
"pi": {
|
|
37
|
+
"extensions": [
|
|
38
|
+
"./src/index.ts"
|
|
39
|
+
],
|
|
40
|
+
"skills": [
|
|
41
|
+
"./skills"
|
|
42
|
+
]
|
|
43
|
+
},
|
|
44
|
+
"scripts": {
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"typecheck": "tsc --noEmit",
|
|
48
|
+
"check": "npm run typecheck && npm test"
|
|
49
|
+
},
|
|
50
|
+
"engines": {
|
|
51
|
+
"node": ">=22"
|
|
52
|
+
},
|
|
53
|
+
"dependencies": {
|
|
54
|
+
"@modelcontextprotocol/sdk": "^1.25.1",
|
|
55
|
+
"@mozilla/readability": "^0.6.0",
|
|
56
|
+
"@napi-rs/keyring": "^2.0.0",
|
|
57
|
+
"linkedom": "^0.18.12"
|
|
58
|
+
},
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"@earendil-works/pi-ai": "*",
|
|
61
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
62
|
+
"@earendil-works/pi-tui": "*",
|
|
63
|
+
"typebox": "*"
|
|
64
|
+
},
|
|
65
|
+
"devDependencies": {
|
|
66
|
+
"@earendil-works/pi-ai": "*",
|
|
67
|
+
"@earendil-works/pi-coding-agent": "*",
|
|
68
|
+
"@earendil-works/pi-tui": "*",
|
|
69
|
+
"@types/node": "^24.3.0",
|
|
70
|
+
"typebox": "*",
|
|
71
|
+
"typescript": "^5.9.2",
|
|
72
|
+
"vitest": "^3.2.4"
|
|
73
|
+
},
|
|
74
|
+
"peerDependenciesMeta": {
|
|
75
|
+
"@earendil-works/pi-ai": {
|
|
76
|
+
"optional": true
|
|
77
|
+
},
|
|
78
|
+
"@earendil-works/pi-coding-agent": {
|
|
79
|
+
"optional": true
|
|
80
|
+
},
|
|
81
|
+
"@earendil-works/pi-tui": {
|
|
82
|
+
"optional": true
|
|
83
|
+
},
|
|
84
|
+
"typebox": {
|
|
85
|
+
"optional": true
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pi-essentials
|
|
3
|
+
description: Combined MCP, web, subagent, todo, and ask-user tools for the Pi Coding Agent. Use when the task needs external tools, web research, delegated agents, a task list, or a real user decision.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# pi-essentials
|
|
7
|
+
|
|
8
|
+
This session has a bundled plugin. Prefer these tools over inventing shell workarounds.
|
|
9
|
+
|
|
10
|
+
## MCP
|
|
11
|
+
|
|
12
|
+
- `mcp({ action: "search", query })` then `describe` then `call`.
|
|
13
|
+
- Do not assume every MCP tool is already in the tool list.
|
|
14
|
+
- If a server needs OAuth, `mcp({ action: "auth", server })`.
|
|
15
|
+
- Use `mcp({ action: "enable", server })` or `mcp({ action: "disable", server })` to manage server availability.
|
|
16
|
+
- `mcp({ action: "status" })` explains why a server has no tools.
|
|
17
|
+
- MCP calls include non-duplicated `structuredContent`. Use prefixed names when an original name is ambiguous; server `isError` results are tool failures.
|
|
18
|
+
|
|
19
|
+
## Web
|
|
20
|
+
|
|
21
|
+
- `web_search` for discovery, `web_fetch` for a specific URL.
|
|
22
|
+
- Search count aliases have precedence `numResults` → `limit` → `num_search_results` → configured default.
|
|
23
|
+
- Results are shown collapsed; there is no need to restate them back to the user.
|
|
24
|
+
- Pass exactly one of `url` or `cacheId` to `web_fetch`. For truncation, use the printed `cacheId` and `offset`.
|
|
25
|
+
- `web_fetch` reads text pages only. It will not download binaries or run page JavaScript.
|
|
26
|
+
|
|
27
|
+
## Subagents
|
|
28
|
+
|
|
29
|
+
- `scout` for recon, `worker` to implement, `reviewer` to check, `oracle` for a second opinion.
|
|
30
|
+
- Pass only the task. Do not paste the entire parent transcript.
|
|
31
|
+
- `{ tasks: [...] }` runs in parallel; `{ chain: [...] }` runs in order and substitutes `{previous}`.
|
|
32
|
+
- `outputSchema` requires a structured object result; a per-job schema overrides the top-level default.
|
|
33
|
+
- `isolation: "worktree"` requires a clean Git tree. It returns changed files and a patch artifact after removing the temporary checkout; it never auto-applies the patch. Parallel jobs are separate, while isolated chain steps share a worktree.
|
|
34
|
+
- The spawn budget is per session, so batch related work instead of spawning one child at a time.
|
|
35
|
+
|
|
36
|
+
## Todos
|
|
37
|
+
|
|
38
|
+
- `todo` supports `list/create/update/complete/reopen/block/unblock/abandon/delete/clear/sync` and statuses `pending/in_progress/completed/blocked/abandoned`.
|
|
39
|
+
- Keep at most one item `in_progress`; use `phase` for workflow grouping and `blocker` for an explicit blocking reason.
|
|
40
|
+
- Use `blockedBy` for real ordering constraints; the tool rejects cycles and missing ids.
|
|
41
|
+
- `sync` replaces the complete snapshot while preserving supplied IDs, dependencies, metadata, and statuses.
|
|
42
|
+
- The user sees a live panel above the editor, so keep todo text short and specific.
|
|
43
|
+
|
|
44
|
+
## Questions
|
|
45
|
+
|
|
46
|
+
- `ask_user_question` only when a genuine user decision is required.
|
|
47
|
+
- Do not ask questions you can answer from the repo or with `web_search`.
|
|
48
|
+
- Give 2-4 distinct options. `allowOther` defaults true; set it false only when free text is invalid.
|
|
49
|
+
- Use `id` for answer correlation and option `value` for machine-readable choices. `recommended` is validated zero-based metadata, not a preselection.
|
|
50
|
+
- `multiple` aliases `multiSelect` (both must agree). Answers include selected labels, values, indices, and custom text.
|